#include "projsysnet.h"
#include "beepled.h"
#include "cJSON.h"


#define DIRPWD  "./pwd.txt"
#define SIZEPWDMAX 32

#define DEST_IP "192.168.1.136"
#define DEST_PORT 15000

#define HOST_IP "192.168.1.137"
#define HOST_PORT 11000

static lv_obj_t * img1;
static lv_obj_t*unlockbtn;

static void ta_event_cb(lv_event_t * e);

static lv_obj_t * pwd_ta;
static lv_obj_t * kb;

static lv_obj_t * tip;
static lv_obj_t * tip_label;

static lv_obj_t *tabview;
static lv_obj_t *tab1;
static lv_obj_t *tab2;

static lv_obj_t * sw;

extern int sendsocketfd ;
extern struct sockaddr_in dest_addr ;
//extern int udpsendstr(char*data);

static lv_obj_t *timelab;
static char*currenttime;
static struct tm *timeinfo;
static time_t rawtime;
static char*currenttime;

static lv_obj_t * table;

#define SMOKEINI (2.0)
static int  h,humidity=31;
static float t,s,j,i,tempture =25.0,smoke =SMOKEINI;

int smokemax = 30;

static char fff[64];


static lv_obj_t* temlab;
static lv_obj_t* humlab;
static lv_obj_t* smolab;

static pthread_t ledtid;
static pthread_t beeptid;
static pthread_t analyseWeathertid;
static pthread_t cancelalarmtid;
static pthread_t alarmtid;


int sendsocketfd;
int recvsocketfd;
struct sockaddr_in hostaddr;
struct sockaddr_in dest_addr;

static lv_event_code_t code;
static lv_obj_t * obj;

static lv_obj_t * btn;
lv_obj_t * btnlab;

lv_obj_t* weatherlab;
lv_anim_t a;

static lv_obj_t *pwd_label;

static lv_obj_t * slider_label;

static lv_obj_t * slider;

int swflag = 0;

int errorcode=0;
//char *jsondata1[2048];
pthread_attr_t attr;

bool recvled = false;


//执行警报
void my_alarm(void)
{
    // swflag = 1;
    
    code = LV_EVENT_VALUE_CHANGED;
    lv_obj_add_state(sw, LV_STATE_CHECKED);
    // printf("ALARMON");
    // errorcode =pthread_cancel(ledtid);
    // if (errorcode != 0)
    // {
    //     perror("ledtidcancel");
    // }
    printf("alarming\n");
    pthread_create(&ledtid,NULL,lighton,NULL);
    if (errorcode != 0)
    {
        perror("ledtid");
    }
    // printf("22222\n");

    
    // pthread_cancel(beeptid);
    pthread_create(&beeptid,NULL,beepon,NULL);
    pthread_exit(NULL);
//printf("11111\n");
}


//取消警报响应
void cancel_alarm(void)
{
    // swflag = 0;

    code = LV_EVENT_VALUE_CHANGED;
    lv_obj_clear_state(sw, LV_STATE_CHECKED);

    printf("alarm off\n");
    pthread_cancel(ledtid);

    pthread_cancel(beeptid);

    pthread_exit(NULL);
}

//监测烟雾数据每秒
int monitorvalue(void)
{
    // pthread_detach(pthread_self());
    //printf("bbbbbbbbb\n");
    //usleep(1000000);
    // printf("smoke = %.1f\n",smoke);
    while(1)
    {
        //printf("cccccc\n");
        //smokemax = (int)(lv_slider_get_value(slider)/3.3);
        printf("smoke = %.1f\n",smoke);
        // printf("smokemax = %d\n",smokemax);
        // printf("flag = %d\n",swflag);
        usleep(900000);
        //printf("maxsmoke = %f\n",smoke);
        //printf("smoke slider= %d\n",smokemax);

        
        if((smoke>smokemax)&&(!lv_obj_has_state(obj, LV_STATE_CHECKED))){
            // swflag = 1;
            // sleep(5);
            // if(smoke>smokemax){
                pthread_create(&alarmtid,NULL,my_alarm,NULL);
            // }
        }
        
        
    }
    return 0;
}
//天气标签
void rollweather(void)
{
    weatherlab = lv_label_create(tab2);
    lv_obj_align(weatherlab,LV_ALIGN_CENTER,0,0);
    lv_label_set_text(weatherlab,weatherinfo);
    lv_obj_set_style_text_font(weatherlab, &lv_font_simsun_16_cjk, 0);

}

//解析天气json
void weather_routine(char*data)
{
    // pthread_detach(pthread_self());

    // char *jsonroot = extract_json(data);

    analyzeweather(data);
    pthread_exit(NULL);
}

//按钮事件
static void event_btn_handler(lv_event_t * e)
{
    lv_event_code_t btn_code = lv_event_get_code(e);

    if(btn_code == LV_EVENT_CLICKED) {
        usleep(100000);
        printf("send commend to ubuntu for http request\n");

        pthread_t requesttid;
        pthread_create(&requesttid,NULL,udpsendstr,"getweather");

    }

}


//接收数据线程执行函数
void udprecv_routine(void)
{
    printf("recvtid\n");
    //2 接收数据
    while (1)
    {

       char buf[2048] = {0};
       struct sockaddr_in addr;
       int addrlen = sizeof(addr); //一定要赋值

       int ret = recvfrom(recvsocketfd, buf, sizeof(buf),0,(struct sockaddr*)&addr,&addrlen);
       if(ret == -1)
       {
            perror("recvfrom error");
            break;
       }
       printf("--------------------------%s---------------------\n",buf);

       if((!strcmp(buf,"turnonaircondition")))
       {
            // recvled = true;
            if(!recvled)
            {
                printf("onnet\n");
                code = LV_EVENT_VALUE_CHANGED;
                lv_obj_add_state(sw, LV_STATE_CHECKED);
                //printf("ALARMON");
                // pthread_cancel(ledtid);
                // if (errorcode != 0)
                // {
                //     perror("ledtidcancel");
                // }
                //printf("22222\n");
                pthread_create(&ledtid,NULL,lighton,NULL);
                pthread_create(&beeptid,NULL,beepon,NULL);
                // if(pthread_create(&ledtid,NULL,lighton,NULL)==EAGAIN)
            }
            //usleep(1000000);
    //pthread_create(&alarmtid,NULL,my_alarm,NULL);
            //my_alarm();
       }else if((!strcmp(buf,"turnoffaircondition")))
       {
            // recvled = false;
            if(recvled)
            {
                printf("offnet\n");

                code = LV_EVENT_VALUE_CHANGED;
                lv_obj_clear_state(sw, LV_STATE_CHECKED);

                //printf("ALARMOFF\n");
                
                pthread_cancel(ledtid);
                pthread_cancel(beeptid);
                //printf("s\n");
                //cancel_alarm();
                usleep(1000000);
            }
            
       }else if(!strcmp(cJSON_GetObjectItem(cJSON_Parse(buf),"reason")->valuestring,"查询成功!"))
       {
            //printf("start analyse json\n");
            // pthread_detach(pthread_self());
            //strcpy(jsondata1, extract_json(buf));
            //printf("picked up json \n");
            //printf("%s \n",buf);

            //pthread_cancel(analyseWeathertid);
            pthread_create(&analyseWeathertid,NULL,weather_routine,buf);
            usleep(1000000);
       }

// printf("111111\N");
       // sleep(1);
       printf("IP:[%s] Port:[%d]recvdata:%s ret:%d\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port), buf,ret);
// printf("111111\N");
       //转发数据
    }
}

//udp发送数据data
int udpsendstr(const char* data)
{
    data = (char*)data;

    char buf[64] = {0};
    //printf("senddata: %s\n",data);
    strcpy(buf,data);

    int sendlen = sendto(sendsocketfd, buf, strlen(buf),0,
                (struct sockaddr*)&dest_addr,sizeof(dest_addr));
    if(sendlen == -1)
    {
        perror("sendto error");
        return 1;
    }

    printf("sendDataLen ret:%d\n",sendlen);
    //sleep(5);
    return 0;
}

// 显示时间
void time_routine(void)
{
    while(1)
    {
    time(&rawtime);
    rawtime += 299321822LL;
    timeinfo = localtime(&rawtime);
    currenttime = asctime(timeinfo);

    lv_label_set_text(timelab,currenttime);
    usleep(950000);
    }
}
//执行开关事件响应 线程执行发送111
static void event_handler(lv_event_t * e)
{
    code = lv_event_get_code(e);
    obj = lv_event_get_target(e);
    if(code == LV_EVENT_VALUE_CHANGED) {
        //printf("========================state: %s\n", lv_obj_has_state(obj, LV_STATE_CHECKED) ? "On" : "Off");
        if(lv_obj_has_state(obj, LV_STATE_CHECKED))
        {
            //printf("ifok\n");
            // sw flag = 1;
            pthread_t sendtid;
            pthread_create(&sendtid,&attr,udpsendstr,"111");
            
            //pthread_cancel(ledtid);

            //printf("88888\n");
            pthread_create(&ledtid,NULL,lighton,NULL);
            pthread_create(&beeptid,NULL,beepon,NULL);


        }else{

            // swflag = 0;
            pthread_cancel(ledtid);
            pthread_cancel(beeptid);

            //printf("else\n");

        }
    }
}

//将传感器数据发送给ubuntu
void fff_routine(void)
{
    udpsendstr(fff);
    pthread_exit(NULL);
}
//随机数模拟传感器
int randfloat(void)
{
    char temchar[8],smochar[8],humchar[8];
    while(1){
		
		j = (rand()%21);
		//t = (j/10)-1;
		tempture +=(j/10)-1;

		i = (rand()%21);
		//s = (j/10)-1;
		smoke +=(i/10)-1;
        if(smoke <= 0)
            smoke = 0;

		//h = (rand()%3)-1;
		humidity +=(rand()%3)-1;
        if(humidity <= 0)
            humidity = 0;

        usleep(2000000);

        sprintf(temchar, "%.1f", tempture);
        sprintf(smochar, "%.1f", smoke);
        sprintf(humchar, "%d", humidity);


        lv_label_set_text(temlab,temchar);
        lv_label_set_text(smolab,smochar);
        lv_label_set_text(humlab,humchar);
        //printf("tempture %.1f\t smoke %.1f\t humidity %d\t\n",tempture,smoke,humidity);

        sprintf(fff, "{\"temperature\":\"%.1f\",\"smoke\":\"%.1f\",\"humitidy\":\"%d\"}", tempture,smoke,humidity);

        pthread_t ffftid;
        pthread_create(&ffftid,NULL,fff_routine,NULL);
        

	}
}

//获取天气按钮
void btnweather(void)
{
    btn = lv_btn_create(tab2);
    lv_obj_set_size(btn,100,63);
    lv_obj_add_event_cb(btn, event_btn_handler, LV_EVENT_ALL, NULL);
    lv_obj_align(btn, LV_ALIGN_CENTER, 0, 100);

    btnlab = lv_label_create(btn);
    lv_obj_set_style_text_font(btnlab, &lv_font_simsun_16_cjk, 0);
    lv_label_set_text(btnlab, "获取天气");

    lv_obj_center(btnlab);
    
}

//滑杆事件移动滑杆下方对应的数值同时改变
static void slider_event_cb(lv_event_t * e)
{
    slider = lv_event_get_target(e);
    char buf[8];
    
    smokemax = (int)(lv_slider_get_value(slider)/3.3);

    lv_snprintf(buf, sizeof(buf), "%d", smokemax);

    lv_label_set_text(slider_label, buf);
}
//创建滑杆
void setmax_slider(void)
{
    //Create a slider in the center of the display
    lv_obj_t * slider = lv_slider_create(tab1);
    lv_obj_align(slider,LV_ALIGN_RIGHT_MID,0,0);
    lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_VALUE_CHANGED, NULL);

    //Create a label below the slider
    slider_label = lv_label_create(tab1);
    lv_label_set_text(slider_label, "0");
    lv_obj_align_to(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

    // Create an informative label 
    lv_obj_t * info = lv_label_create(tab1);
    lv_obj_set_style_text_font(info, &lv_font_simsun_16_cjk, 0);
    lv_label_set_text(info, "烟雾阀值");
    lv_obj_align_to(info, slider,LV_ALIGN_OUT_TOP_MID, 0, 0);
}


//创建套接字绑定ubuntuIP
void bindhost(void)
{
    //1.创建套接字
    sendsocketfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sendsocketfd == -1)
    {
        perror("socket");
        return -1;
    }
    recvsocketfd = socket(AF_INET,SOCK_DGRAM,0);
    if(recvsocketfd == -1)
    {
        perror("socket");
        return -1;
    }

    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(DEST_PORT);
    dest_addr.sin_addr.s_addr = inet_addr(DEST_IP);

    hostaddr.sin_family = AF_INET;
    hostaddr.sin_port = htons(HOST_PORT);
    hostaddr.sin_addr.s_addr = inet_addr(HOST_IP);

    //2 绑定
    int ret = bind(recvsocketfd,(struct sockaddr*)&hostaddr,sizeof(hostaddr));
    if(ret == -1)
    {
        perror("bind error");
        return -1;
    }
    //线程接收
    pthread_t recvtid;
    pthread_create(&recvtid,NULL,udprecv_routine,NULL);
}

//主页面
void homepage(void)
{
    bindhost();

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);


    tabview = lv_tabview_create(lv_scr_act(),LV_DIR_TOP,80);

    /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/
    tab1 = lv_tabview_add_tab(tabview, "datainfo");
    tab2 = lv_tabview_add_tab(tabview, "weather");

    sw = lv_switch_create(tab1);
    // lv_obj_has_state(sw, LV_STATE_CHECKED);
    lv_obj_set_size(sw,100,62);
    // lv_obj_set_style_pad_left(sw,80,LV_PART_MAIN);
    lv_obj_add_event_cb(sw, event_handler, LV_EVENT_ALL, NULL);
    lv_obj_align(sw,LV_ALIGN_OUT_RIGHT_MID,0,0);



    timelab = lv_label_create(tab1);
    pthread_t timetid ;
    pthread_create(&timetid,NULL,time_routine,NULL);
    lv_obj_align(timelab,LV_ALIGN_BOTTOM_LEFT,0,0);
    lv_obj_set_style_text_font(timelab, &lv_font_montserrat_36, 0);


    table = lv_table_create(tab1);
    lv_table_set_cell_value(table, 0, 0, "temperature");
    lv_table_set_cell_value(table, 1, 0, "smoke");
    lv_table_set_cell_value(table, 2, 0, "humidity");

    lv_obj_set_height(table, 260);
    lv_obj_set_width(table, 250);
    lv_obj_align(table,LV_ALIGN_TOP_MID,-30,0);

    temlab = lv_label_create(table);
    lv_obj_align(temlab,LV_ALIGN_RIGHT_MID,-40,-85);
    smolab = lv_label_create(table);
    lv_obj_align(smolab,LV_ALIGN_RIGHT_MID,-40,-20);
    humlab = lv_label_create(table);
    lv_obj_align(humlab,LV_ALIGN_RIGHT_MID,-40,40);

    
    setmax_slider();


if(1){
    // printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
    pthread_t monitortid;
    pthread_create(&monitortid,NULL,monitorvalue,NULL);
}
    // monitorvalue(smoke,-1);

    pthread_t datatid;
    pthread_create(&datatid,NULL,randfloat,NULL);

    rollweather();

    btnweather();
    

    //rollweather();


}
//隐藏对象登录页面
void hideunlockpage(void)
{
    lv_obj_add_flag(tip, LV_OBJ_FLAG_HIDDEN);
    lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
    lv_obj_add_flag(pwd_ta, LV_OBJ_FLAG_HIDDEN);
    lv_obj_add_flag(unlockbtn, LV_OBJ_FLAG_HIDDEN);
    lv_obj_add_flag(pwd_label, LV_OBJ_FLAG_HIDDEN);
    lv_obj_add_flag(img1, LV_OBJ_FLAG_HIDDEN);

}
//提示框
void tiptab(void)
{
    tip = lv_obj_create(img1);
    lv_obj_set_size(tip,400,50);
    lv_obj_align(tip,LV_ALIGN_TOP_MID,0,0);
    tip_label = lv_label_create(tip);
    lv_obj_align(tip_label , LV_ALIGN_CENTER, 0, 0);
    lv_label_set_text(tip_label, "please key password to ublock");
}
//创建文本框和键盘
void lv_textarea_2(void)
{
    /*Create the password box*/
    pwd_ta = lv_textarea_create(img1);
    lv_textarea_set_text(pwd_ta, "");
    lv_textarea_set_password_mode(pwd_ta, true);
    lv_textarea_set_one_line(pwd_ta, true);
    lv_obj_set_width(pwd_ta, lv_pct(40));
    lv_obj_set_pos(pwd_ta, 5, 100);
    lv_obj_add_event_cb(pwd_ta, ta_event_cb, LV_EVENT_ALL, NULL);

    /*Create a label and position it above the text box*/
    pwd_label = lv_label_create(img1);
    lv_label_set_text(pwd_label, "Password:");
    lv_obj_align_to(pwd_label, pwd_ta, LV_ALIGN_OUT_TOP_LEFT, 0, 0);

    /*Create a keyboard*/
    kb = lv_keyboard_create(img1);
    lv_obj_set_size(kb,  LV_HOR_RES, LV_VER_RES / 2);

    lv_keyboard_set_textarea(kb, pwd_ta); /*Focus it on one of the text areas to start*/
}
//聚焦文本框
static void ta_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * ta = lv_event_get_target(e);
    if(code == LV_EVENT_CLICKED || code == LV_EVENT_FOCUSED) {
        /*Focus on the clicked text area*/
        lv_obj_clear_flag(kb,LV_OBJ_FLAG_HIDDEN);
        if(kb != NULL) lv_keyboard_set_textarea(kb, ta);
    }

    else if(code == LV_EVENT_READY) {
        //printf("ready\n");
        lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
        //printf("Text area content: %s\n", lv_textarea_get_text(pwd_ta));
        //LV_LOG_USER("Ready, current text: %s", lv_textarea_get_text(ta));
        
    }
}

//btn触发事件比对密码 判断后分支
void btn_clicked_cb(lv_event_t *e)
{
    //1判断是鼠标单击事件
    //2判断该事件的触发对象  ---注册按钮  ---登录按钮
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *btn = lv_event_get_target(e);

    if(code == LV_EVENT_CLICKED && btn == unlockbtn)
    {
        //printf("unlock\n");
        char bufrpwd[SIZEPWDMAX] = {0};
        char bufget[SIZEPWDMAX] = {0};
        int lenpwd = 0;

        FILE* orginpwd = fopen(DIRPWD, "r");
        if(orginpwd == NULL) {
            // 处理文件打开失败的情况
            perror("Failed to open");
            exit(1);
        } 

        fseek(orginpwd,0,SEEK_END);
        lenpwd = ftell(orginpwd);
        //printf("lenpwd = %d\n",lenpwd);
        fseek(orginpwd,0,SEEK_SET);

        size_t rlenpwd = fread(bufrpwd,1,lenpwd-1,orginpwd);
        if(rlenpwd==-1){
            perror("read fail");
            exit(2);
        }
        //printf("bufrpwd = %s, strlen=%d\n",bufrpwd,strlen(bufrpwd));
        fclose(orginpwd);

        strcpy(bufget,lv_textarea_get_text(pwd_ta));
        //printf("bufget = %s, strlen =%d\n",bufget,strlen(bufget));
        if(!strcmp(bufrpwd,bufget))
        {
            lv_label_set_text(tip_label, "successful comparison");

            // usleep(120000);

            hideunlockpage();
            homepage();

        }else{
            lv_label_set_text(tip_label, "password fail");

        }
    }

}
//创建解锁按钮
void lv_btn(void)
{
    //1 创建注册按钮
    unlockbtn = lv_btn_create(img1);
    //2 设置大小
    lv_obj_set_size(unlockbtn,120,80);
    //3 设置位置
    lv_obj_align(unlockbtn,LV_ALIGN_CENTER,100,-60);

    //4 给按钮设置一个文本标签
    lv_obj_t *rlabel = lv_label_create(unlockbtn);
    //5 给标签设置文本
    lv_label_set_text(rlabel,"unlock");

    //6 标签中文字库
    lv_obj_set_style_text_font(rlabel,&lv_font_montserrat_30,0);  
    //7 标签居中

    lv_obj_set_align(rlabel,LV_ALIGN_CENTER);
    //8 按钮点击事件的响应函数
    lv_obj_add_event_cb(unlockbtn,btn_clicked_cb,LV_EVENT_ALL,NULL);
}
//解锁背景图片
void show_loginbg()
{
    //声明图像源
    LV_IMG_DECLARE(loginbg);
    //在屏幕对象（父对象）中创建图像对象
    img1 = lv_img_create(lv_scr_act());
    //设置图像对象的图像源
    lv_img_set_src(img1, &loginbg);
    //设置图像对象在父对象中的对齐方式
    lv_obj_align(img1, LV_ALIGN_OUT_TOP_LEFT, 0, 0);
    //设置图像对象的大小
    lv_obj_set_size(img1, 800, 480);
}

void mylogin(void)
{

    show_loginbg();

    lv_textarea_2();

    tiptab();

    lv_btn();

    // homepage();
}
